////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2007.
// -------------------------------------------------------------------------
//  File name:   AreaGrid.h
//  Version:     v1.00
//  Created:     08/03/2007 by Michael Smith.
//  Compilers:   Visual Studio.NET 2005
//  Description: 
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////
#ifndef __AREAGRID_H__
#define __AREAGRID_H__

class CArea;

class CAreaBitField
{
public:

	//default, mem will come from global pool
	CAreaBitField();
	~CAreaBitField();

	void SetArea(uint32 areaIndex);
	void ClearArea(uint32 areaIndex);
	bool CheckArea(uint32 areaIndex);
	
	//static 

	//allocate mem for all bit arrays in grid
	//saves overhead of many small allocs
	static void AllocateMem();

	//Free all grid mem
	static void FreeMem();

	//Setup grid mem
	static void InitGrid(uint32 nBits, uint32 nGridCells);

	//And 2 bitfields and populate an array of area indices
	static uint32* GetAreas(CAreaBitField &lhs, CAreaBitField& rhs, uint32 &nAreasOut);

	static uint32 GetBitFieldSizeU32() {return s_bitFieldSizeU32;}

protected:

	uint32 *m_pbitField;
	
	//Num u32s needed to store all areas
	static uint32 s_bitFieldSizeU32;

	//Max num areas
	static uint32 s_maxNumAreas;

	//base ptr to mem
	static uint32* s_pBitArrayMem;

	//current ptr to mem, incremented in Bit Array ctor
	static uint32* s_pBitArrayMemCurrent;
	
	//total num grid cells
	static uint32 s_nGridCells;

	//list of area indices, populated when you cal GetAreas
	static uint32* s_pAreaList;

	//temp mem for &-ing to bit areas, prevent alloc at runtime
	static uint32* s_pTempBitMem;
};

class CAreaGrid
{
public:

	CAreaGrid();

	void Compile(CEntitySystem* pEntitySystem, std::vector<CArea*>& areas);
	void Reset();
	uint32* GetAreas(const Vec3& position, uint32& nAreas);
	void Draw();
	
	uint32 GetNumAreas() const {return m_pAreas->size();}

protected:
	
	float GetMaximumEffectRadius(CArea *pArea);

#ifndef _RELEASE
	void Debug_CheckBB(Vec2 &vBBCentre, Vec2 &vBBExtent, uint32 areaIndex);
#endif

	static const uint32 GRID_CELL_SIZE;
	static const float GRID_CELL_SIZE_R;

	CEntitySystem* m_pEntitySystem;
	std::vector<CArea*>* m_pAreas;

	//slice x and y
	CAreaBitField* m_areaSliceX;
	CAreaBitField* m_areaSliceY;

	uint32 m_nCells;

};



#endif //__AREAGRID_H__
